package com.mycode.decorator10;

import com.mycode.decorator10.resolve.*;

/**
 * 装饰模式：动态地给一个对象增加一些额外的职责，就增加对象功能来说，装饰模式比生产子类实现更为灵活
 * 装饰模式虽然好，但有一个问题：客户端希望单独调用具体装饰类增加的方法，而不想通过抽象构件中声明的方法来调用新增方法时将遇到一些麻烦
 * 装饰模式降低了系统的耦合度，可以动态地增加或删除对象的职责，并使得需要装饰的具体构建类和具体装饰类可以独立变化
 *
 * 主要优点：
 *     1、对于扩展一个对象的功能，装饰模式比继承更加灵活性
 *     2、可以通过动态的方式扩展对象的功能，通过配置文件可以在运行时选择不同的具体装饰类
 *     3、可以对一个对象进行多次修饰，通过使用不同的具体装饰类可以进行排列组合，实现不同效果
 *     4、具体构件类与具体装饰类可以独立变化，用户可以根据需要增加具体构建类和具体装饰类
 *
 * 主要缺点：
 *     1、可能湖产生很多小对象，这些对象的区别在于它们之间相互连接的方法有所不同，而不是它们的类或者属性值有所不同，大量小对象会占用一定的系统资源，影响性能
 *     2、因为比继承灵活，同时意味比继承更容易出错，排错困难，对于多次装饰的对象，调试时虚招错误需要逐级排查，较为繁琐
 *
 * 使用场景：
 *     1、在不影响其他对象的情况下，以动态、透明的方法给单个对象添加职责
 *     2、当不能采用继承的方式对系统进行扩展或采用继承不利于系统扩展和维护时可以使用装饰模式
 */
public class Bootstrap {

    public static void main(String[] args) {
        // 定义具体构件
        Component component = new Window();
        // 定义装饰后的构件
        Component componentSB = new ScrollBarDecorator(component);
        componentSB.display();
        System.out.println("-------------------------------------");
        // 第二次装饰
        Component componentBB = new BlackBorderDecorator(componentSB);
        componentBB.display();

        System.out.println("==========================================");
        ScrollBarDecorator scrollBarDecorator = new ScrollBarDecorator(component);
        componentBB = new BlackBorderDecorator(scrollBarDecorator);
        componentBB.display();


    }
}
